package org.garden.common.utils;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

public class DateUtil {

    /**
     * 字符串时间格式
     *
     * @param time   时间
     * @param format format
     * @return 字符串时间
     */
    public static String format(LocalDateTime time, String format) {
        return time.format(DateTimeFormatter.ofPattern(format));
    }

    /**
     * 某天的开始时间
     *
     * @param time LocalDateTime
     * @return LocalDateTime
     */
    public static LocalDateTime dayStart(LocalDateTime time) {
        return time.withHour(0).withMinute(0).withSecond(0).withNano(0);
    }

    /**
     * 某天的结束时间
     *
     * @param time LocalDateTime
     * @return LocalDateTime
     */
    public static LocalDateTime dayEnd(LocalDateTime time) {
        return time.withHour(23).withMinute(59).withSecond(59).withNano(999999999);
    }

    /**
     * 某天的结束时间
     *
     * @param date Date
     * @return Date
     */
    public static Date dayEnd(Date date) {
        Calendar calendar = Calendar.getInstance();
        if (null != date) {
            calendar.setTime(date);
        }
        calendar.set(calendar.get(1), calendar.get(2), calendar.get(5), 23, 59, 59);
        calendar.set(14, 999);
        return new Timestamp(calendar.getTimeInMillis());
    }


    /**
     * 某月的第一天
     *
     * @param time LocalDateTime
     * @return LocalDateTime
     */
    public static LocalDateTime monthStart(LocalDateTime time) {
        LocalDateTime first = time.with(TemporalAdjusters.firstDayOfMonth());
        return LocalDateTime.of(first.toLocalDate(), LocalTime.MIN);
    }

    /**
     * 某月的最后一天
     *
     * @param time LocalDateTime
     * @return LocalDateTime
     */
    public static LocalDateTime monthEnd(LocalDateTime time) {
        LocalDateTime last = time.with(TemporalAdjusters.lastDayOfMonth());
        return LocalDateTime.of(last.toLocalDate(), LocalTime.MIN);
    }

    /**
     * Date 转 LocalDateTime
     *
     * @param date Date
     * @return LocalDateTime
     */
    public static LocalDateTime convert(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }

    /**
     * LocalDateTime 转 Date
     *
     * @param localDateTime LocalDateTime
     * @return Date
     */
    public static Date convert(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * LocalDateTime 转 Date
     * @param data
     * @return
     */
    public static Map<String, Object> convertDate(Map<String, Object> data) {
        for (String key: data.keySet()) {
            Object object = data.get(key);
            if (object instanceof LocalDateTime) {
                LocalDateTime localDateTime = (LocalDateTime)object;
                data.put(key, convert(localDateTime));
            }
        }
        return data;
    }

    public static Date getDate(Object date) {
        if (date == null) {
            return null;
        }
        if (date instanceof LocalDateTime) {
            LocalDateTime localDateTime = (LocalDateTime)date;
            return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
        } else {
            return (Date)date;
        }
    }
}
